package com.njcb.ams.util;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.njcb.ams.support.exception.ExceptionUtil;

/**
 * @author liuyanlong
 */
public class AmsObjectUtils {
	private static final Logger logger = LoggerFactory.getLogger(AmsObjectUtils.class);

	/**
	 * 对象克隆
	 * 
	 * @param t
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static final <T> T clone(T t) {
		if (t == null) {
			return null;
		}
		if (t instanceof Serializable) {
			return (T) SerializationUtils.clone((Serializable) t);
		}
		T result = null;
		if (t instanceof Cloneable) {
			try {
				result = (T) ObjectUtils.clone(t);
			} catch (Throwable e) {
				ExceptionUtil.throwAppException(e.getMessage());
			}
		}
		return result;
	}
	

	/**
	 * 访问对象成员属性值值
	 * 
	 * @param obj
	 * @param field
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public static final Object getFieldValue(Object obj, String field) throws Exception {
		if (obj == null) {
			return null;
		}

		Object result = null;
		if (obj instanceof Map) {
			return ((Map) obj).get(field);
		}

		Method getterMethod = null;
		try {
			getterMethod = obj.getClass().getMethod("get" + StringUtils.capitalize(field));
		} catch (Exception e) {
			logger.debug(field + "没有get方法");
		}
		if (getterMethod == null) {
			try {
				getterMethod = obj.getClass().getMethod("is" + StringUtils.capitalize(field));
			} catch (Exception e) {
				logger.debug(field + "没有is方法");
			}
		}
		if (getterMethod == null) {
			Field privateField;
			try {
				privateField = obj.getClass().getDeclaredField(field);
				privateField.setAccessible(true);
				result = privateField.get(obj);
			} catch (Exception e) {
				throw new Exception("field[" + field + "] doesn't exist.");
			}
		} else {
			try {
				result = getterMethod.invoke(obj);
			} catch (Exception e) {
				logger.debug(field + "执行方法错误");
			}
		}
		return result;
	}

}
